<template>
    <div class="tree-box-inner">
        <div class="btn-box">
            <el-button icon="el-icon-circle-plus" type="text" title="新增角色组"
                :disabled="!currentNode.id || !currentNode.nodeType" @click="addNode"></el-button>
            <el-button icon="el-icon-edit-outline" type="text" title="修改角色组"
                :disabled="!currentNode.id || !currentNode.nodeType" @click="editNode"></el-button>
            <el-button icon="el-icon-delete-solid" type="text" title="删除角色组"
                :disabled="!currentNode.id || !currentNode.nodeType" @click="deleteNode"></el-button>
            <el-button icon="el-icon-search" class="btn-search" type="text" title="搜索" @click="showinput=!showinput">
            </el-button>
        </div>
        <div class="search-input" v-if="showinput">
            <el-input size="mini" clearable placeholder="输入检索条件" v-model="filterText"></el-input>
        </div>
        <div class="treediv">
            <el-tree ref="tree" :data="treeData" :props="defaultProps" node-key="id" highlight-current
                :filter-node-method="filterNode" @node-click="nodeClick">
                <span class="custom-tree-node" slot-scope="{ node, data }">
                    <span class="label">{{ node.label }}</span>
                    <span class="button-wrap">
                        <span class="button add" title="新增角色" @click.stop="addRole(node, data)"
                            v-if="data.nodeType == 'cate'"></span>
                        <span class="button edit" title="修改角色" @click.stop="() => editRole(node, data)"
                            v-if="!data.nodeType"></span>
                        <span class="button remove" title="删除角色" @click.stop="() => removeRole(node, data)"
                            v-if="!data.nodeType"></span>
                    </span>
                </span>
            </el-tree>
        </div>
        <!-- 新增角色组 -->
        <el-dialog :title="title" :visible.sync="show" :append-to-body="true" :close-on-click-modal="false"
            :before-close="closeRoleGroup">
            <el-form class="layout-wrap" :model="ruleForm" :rules="rules" label-width="160px" label-position="left"
                ref="form" label-suffix="：">
                <el-form-item label="分组名称" prop="name">
                    <el-input v-model="ruleForm.name"></el-input>
                </el-form-item>
                <el-form-item label="显示顺序" prop="orderNum">
                    <el-input-number v-model="ruleForm.orderNum" size="medium" :min="0" :max="9999"></el-input-number>
                </el-form-item>
                <el-form-item label="说明" prop="descr">
                    <el-input type="textarea" :rows="4" v-model="ruleForm.descr"></el-input>
                    <text-length v-model="ruleForm.descr" :length.sync="ruleForm.descr_l" :max="256"></text-length>
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button type="primary" @click="saveRoleGroup" :loading="loading">保存</el-button>
                <el-button @click="closeRoleGroup">取消</el-button>
            </div>
        </el-dialog>
        <!-- 新增角色 -->
        <el-dialog :title="title2" :visible.sync="show2" :append-to-body="true" :close-on-click-modal="false"
            :before-close="closeRole">
            <el-form class="layout-wrap" :model="postForm" label-width="160px" :rules="postRules" label-position="left"
                ref="form2" label-suffix="：">
                <el-form-item label="角色名称" prop="name">
                    <el-input v-model="postForm.name"></el-input>
                </el-form-item>
                <el-form-item label="显示顺序" prop="">
                    <el-input-number v-model="postForm.orderNum" size="medium" :min="0" :max="9999"></el-input-number>
                </el-form-item>
                <el-form-item label="说明" prop="descr">
                    <el-input type="textarea" :rows="4" v-model="postForm.descr"></el-input>
                    <text-length v-model="postForm.descr" :length.sync="postForm.descr_l" :max="256"></text-length>
                </el-form-item>
            </el-form>
            <div slot="footer">
                <el-button type="primary" @click="saveRole" :loading="loading2">保存</el-button>
                <el-button @click="closeRole">取消</el-button>
            </div>
        </el-dialog>
    </div>

</template>

<script>
    import textLength from '@/components/textLength';
    import {
        getRoleTree,
        newRowGroup,
        updateRowGroup,
        delRowGroupById,
        roleSave,
        roleUpdate,
        delRoleById,
        updateRoleCateOrder,
        updateRoleOrder
    } from '../service.js';
    import {
        transformTozTreeFormat
    } from '@/utils/Tools';
    import {
        auth
    } from '@/mixins/mixins';

    export default {
        name: 'deptTree', // 机构树
        props: {},
        components: {
            textLength
        },
        mixins: [auth],
        data() {
            var validate_descr = (rule, value, callback) => {
                if (this.ruleForm.descr_l > 256) {
                    callback(new Error())
                } else {
                    callback();
                }
            }
            var validate_descr2 = (rule, value, callback) => {
                if (this.postForm.descr_l > 256) {
                    callback(new Error())
                } else {
                    callback();
                }
            }
            return {
                showinput: false,
                show: false,
                show2: false,
                title: '新增角色分组',
                title2: '新增角色',
                filterText: '',
                treeData: [],
                currentNode: {}, // 选中的当前节点
                defaultProps: {
                    label: 'name',
                    children: 'children',
                    isLeaf: 'leaf',
                },
                ruleForm: { // 角色组form
                    name: '',
                    orderNum: 0,
                    descr: '',
                    descr_l: 0,
                },
                postForm: { // 角色form
                    name: '',
                    orderNum: 0,
                    descr: '',
                    descr_l: 0,
                    roleTypeCode: '',
                    roleTypeName: ''
                },
                rules: {
                    name: [{
                            required: true,
                            message: '分组名称必填',
                            trigger: 'change'
                        },
                        {
                            min: 0,
                            max: 20,
                            message: '长度限制20位',
                            trigger: 'change'
                        },
                    ],
                    descr: [{
                        validator: validate_descr,
                        message: '长度限制256位',
                        trigger: 'change'
                    }, ],

                },
                postRules: {
                    name: [{
                            required: true,
                            message: '角色名称必填',
                            trigger: 'change'
                        },
                        {
                            min: 0,
                            max: 20,
                            message: '长度限制20位',
                            trigger: 'change'
                        },
                    ],
                    descr: [{
                        validator: validate_descr,
                        message: '长度限制256位',
                        trigger: 'change'
                    }, ]
                },
                loading: false,
                loading2: false,
            }
        },
        watch: {
            filterText(val) {
                this.$refs.tree.filter(val);
            }
        },
        mounted() {
            this.$nextTick(() => {
                this.roleTreeInit();
            })
        },
        methods: {
            filterNode(value, data) { // 节点过滤
                if (!value) return true;
                return data.name.indexOf(value) !== -1;
            },
            roleTreeInit() { // 初始化数据
                let params = {
                    columns: 'orderNum',
                    orders: 'ASC'
                };
                getRoleTree(params).then(res => {
                    this.treeData.splice(0, this.treeData.length);
                    if (res.data.code == 1000) {
                        let data = res.data.data;
                        if (Array.isArray(data)) {
                            data = transformTozTreeFormat(data, {
                                parentKey: 'roleTypeCode'
                            });
                            data = data.map(item => {
                                return {
                                    ...item,
                                    nodeType: 'cate'
                                }
                            })
                            this.treeData.push(...data);
                            if (this.treeData.length) { // 默认点击第一项
                                setTimeout(() => {
                                    let Node = this.$refs.tree.getNode(this.treeData[0].id);
                                    this.nodeClick(this.treeData[0], Node, this.$refs.tree);
                                    this.$refs.tree.setCurrentKey(this.treeData[0].id);
                                }, 200)
                            }
                        }
                    }
                }).catch(error => {})
            },
            nodeClick(treeNode, Node, comp) { // 点击事件  treeNode:当前节点 Node: 节点对象Node  comp:组件本身
                this.currentNode = treeNode;
                this.$emit('node-click', treeNode, Node, comp);

                let path = this.$refs.tree.getNodePath(treeNode.id);
                this.$emit('updatePath', path);
            },
            addNode() { // 新增角色分组
                this.title = '新增角色分组';
                this.show = true;
            },
            editNode() { // 修改角色组
                this.title = '修改角色分组';
                this.ruleForm.id = this.currentNode.id;
                this.ruleForm.name = this.currentNode.name;
                this.ruleForm.orderNum = this.currentNode.orderNum;
                this.ruleForm.descr = this.currentNode.descr || '';
                this.show = true;
            },
            deleteNode() { // 删除角色组
                this.$confirm('删除后不能恢复，是否确认？', {
                    title: '提示',
                    type: 'warning'
                }).then(() => {
                    let params = {
                        ids: this.currentNode.id
                    };
                    delRowGroupById(params).then(res => {
                        if (res.data.code == 1000) {
                            let node = this.$refs.tree.getNode(this.currentNode.id);
                            if (node) { // 从树中 删除节点
                                this.$refs.tree.remove(node);
                                if (this.treeData[0]) {
                                    this.$emit('updateCurrentNode', this.treeData[0]);
                                }
                                this.$notify({
                                    title: "提示",
                                    message: "删除成功！",
                                    type: "success"
                                });
                            }
                        }
                    });
                }).catch(() => {})
            },
            saveRoleGroup() { // 新增角色分组
                this.$refs.form.validate(valid => {
                    if (valid) {
                        let params = {
                            id: this.ruleForm.id,
                            name: this.ruleForm.name, // 机构名称
                            orderNum: this.ruleForm.orderNum,
                            descr: this.ruleForm.descr,
                            statusId: 'ACTIVE',
                            statusName: '启用'
                        }
                        if (!this.ruleForm.id) {
                            delete params.id;
                            this.loading = true;
                            newRowGroup(params).then(res => {
                                if (res.data.code == 1000) {
                                    this.$notify({
                                        title: '提示',
                                        type: 'success',
                                        message: '保存成功'
                                    })
                                    this.roleTreeInit();
                                    this.closeRoleGroup();
                                }
                                this.loading = false;
                            }).catch(error => {
                                this.loading = false;
                            })
                        } else {
                            this.loading = true;
                            updateRowGroup(params).then(res => {
                                if (res.data.code == 1000) {
                                    this.$notify({
                                        title: '提示',
                                        type: 'success',
                                        message: '保存成功'
                                    })
                                    this.roleTreeInit();
                                    this.closeRoleGroup();
                                }
                                this.loading = false;
                            }).catch(error => {
                                this.loading = false;
                            })
                        }
                    }
                })
            },
            closeRoleGroup() { // 关闭新增角色分组 弹窗
                this.show = false;
                this.ruleForm.id = '';
                this.$refs.form.resetFields();
            },
            addRole(node, data) {
                this.title2 = '新增角色';
                this.postForm.roleTypeCode = data.id;
                this.postForm.roleTypeName = data.name;
                this.show2 = true;
            },
            editRole(node, data) {
                this.title2 = '修改角色';
                this.postForm.id = data.id;
                this.postForm.name = data.name;
                this.postForm.orderNum = data.orderNum;
                this.postForm.descr = data.descr;
                this.postForm.roleTypeCode = data.roleTypeCode;
                this.postForm.roleTypeName = data.roleTypeName;
                this.show2 = true;
            },
            removeRole(node, data) {
                this.$confirm('确认删除该角色？删除后将不能恢复！', {
                    title: '提示',
                    type: 'warning'
                }).then(() => {
                    let params = {
                        ids: data.id
                    }
                    delRoleById(params).then(res => {
                        if (res.data.code == 1000) {
                            this.$notify({
                                title: '提示',
                                type: 'success',
                                message: '删除成功'
                            })
                            this.roleTreeInit();
                        }
                    })
                }).catch(() => {})
            },
            saveRole() { // 新增角色
                this.$refs.form2.validate(valid => {
                    let params = {
                        id: this.postForm.id,
                        name: this.postForm.name,
                        orderNum: this.postForm.orderNum,
                        roleTypeCode: this.postForm.roleTypeCode,
                        roleTypeName: this.postForm.roleTypeName,
                        descr: this.postForm.descr
                    }
                    if (!this.postForm.id) {
                        this.loading2 = true;
                        roleSave(params).then(res => {
                            if (res.data.code == 1000) {
                                this.$notify({
                                    title: '提示',
                                    type: 'success',
                                    message: '保存成功'
                                })
                                this.roleTreeInit();
                                this.closeRole();
                            }
                            this.loading2 = false;
                        }).catch(error => {
                            this.loading2 = false;
                        })
                    } else {
                        this.loading2 = true;
                        roleUpdate(params).then(res => {
                            if (res.data.code == 1000) {
                                this.$notify({
                                    title: '提示',
                                    type: 'success',
                                    message: '保存成功'
                                })
                                this.roleTreeInit();
                                this.closeRole();
                            }
                            this.loading2 = false;
                        }).catch(error => {
                            this.loading2 = false;
                        })
                    }
                })
            },
            closeRole() {
                this.postForm.id = '';
                this.$refs.form2.resetFields();
                this.show2 = false;
            },


            updateNodeFun(data) { // 更新节点信息
                let Node = this.$refs.tree.getNode(data.id);
                if (Node) {
                    let childNodes = Node.childNodes;
                    let newdata = {
                        ...data,
                        children: childNodes.map(item => item.data)
                    }
                    Node.data = newdata;

                    this.$emit('updateCurrentNode', data);

                    // 更新面包屑
                    let path = this.$refs.tree.getNodePath(data.id);
                    this.$emit('updatePath', path);
                }
            },
            appendNodeFun(data) { // 当前节点追加新节点
                let parentNode = this.$refs.tree.getNode(this.currentNode.id);
                if (parentNode && data.parentId == this.currentNode.id) {
                    this.$refs.tree.append(data, parentNode);
                    parentNode.expanded = true;
                } else {
                    this.roleTreeInit();
                }
            },
            upNode() { // 上移节点
                let parentNode = this.$refs.tree.getNode(this.currentNode.id).parent;
                let cNode = this.$refs.tree.getNode(this.currentNode.id);
                let childNodes = this.$refs.tree.getNode(this.currentNode.id).parent.childNodes;

                let index = childNodes.findIndex(item => item.data.id == this.currentNode.id);
                if (index <= 0) {
                    return
                }

                let currentChild = childNodes.filter(v => v.id !== cNode.id);
                if (currentChild.length) {
                    currentChild.splice(index - 1, 0, cNode);
                    if (currentChild.length) {
                        let ids = currentChild.map(item => item.data.id).join();
                        let params = {
                            ids: ids
                        }
                        if (this.currentNode.nodeType == 'cate') {
                            this.loading = true;
                            updateRoleCateOrder(params).then(res => {
                                if (res.data.code == 1000) {
                                    this.$notify({
                                        title: '提示',
                                        type: 'success',
                                        message: '操作成功'
                                    })
                                    parentNode.childNodes = currentChild;
                                }
                                this.loading = false;
                            }).catch(error => {
                                this.loading = false;
                            })
                        } else {
                            this.loading = true;
                            updateRoleOrder(params).then(res => {
                                if (res.data.code == 1000) {
                                    this.$notify({
                                        title: '提示',
                                        type: 'success',
                                        message: '操作成功'
                                    })
                                    parentNode.childNodes = currentChild;
                                }
                                this.loading = false;
                            }).catch(error => {
                                this.loading = false;
                            })
                        }
                    }
                }
            },
            downNode() { // 下移节点
                let parentNode = this.$refs.tree.getNode(this.currentNode.id).parent;
                let cNode = this.$refs.tree.getNode(this.currentNode.id);
                let childNodes = this.$refs.tree.getNode(this.currentNode.id).parent.childNodes;

                let index = childNodes.findIndex(item => item.data.id == this.currentNode.id);
                if (index >= (childNodes.length - 1)) {
                    return
                }

                let currentChild = childNodes.filter(v => v.id !== cNode.id);
                if (currentChild.length) {
                    currentChild.splice(index + 1, 0, cNode);
                    if (currentChild.length) {
                        let ids = currentChild.map(item => item.data.id).join();
                        let params = {
                            ids: ids
                        }
                        if (this.currentNode.nodeType == 'cate') {
                            this.loading = true;
                            updateRoleCateOrder(params).then(res => {
                                if (res.data.code == 1000) {
                                    this.$notify({
                                        title: '提示',
                                        type: 'success',
                                        message: '操作成功'
                                    })
                                    parentNode.childNodes = currentChild;
                                }
                                this.loading = false;
                            }).catch(error => {
                                this.loading = false;
                            })
                        } else {
                            this.loading = true;
                            updateRoleOrder(params).then(res => {
                                if (res.data.code == 1000) {
                                    this.$notify({
                                        title: '提示',
                                        type: 'success',
                                        message: '操作成功'
                                    })
                                    parentNode.childNodes = currentChild;
                                }
                                this.loading = false;
                            }).catch(error => {
                                this.loading = false;
                            })
                        }
                    }
                }
            },
            updateKeyChildren(key) { // 更新子级的数据  key: 节点key
                let node = this.$refs.tree.getNode(key);
                if (node) {
                    this.$refs.tree.updateKeyChildren(key, data = []);
                }
            },
        }
    }
</script>

<style lang="scss" scoped>
    .lazy-tree {
        height: 100%;
        overflow: hidden;

        .inner-wrap {
            height: 100%;
            display: flex;
            flex-direction: column;

            .btn-box {
                padding: 10px 20px;
                text-align: right;

                /deep/ {
                    .el-button--text {
                        padding: 0;

                        i {
                            font-size: 14px;
                        }
                    }
                }
            }

            .search-bar {
                padding: 0 5px;
                margin-bottom: 5px;
            }

            .tree-box {
                flex: 1;
                padding: 0 5px 5px;
                overflow: auto;

                /deep/ {
                    .el-tree {
                        display: inline-block !important;
                        min-width: 100%;
                    }
                }
            }
        }
    }
</style>